package indi.zhifa.expshare.class001.chemicalmatch.exel;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import indi.zhifa.expshare.class001.chemicalmatch.dao.INickNameRepository;
import indi.zhifa.expshare.class001.chemicalmatch.entity.dto.excel.ChemicalNickNameExcelData;
import indi.zhifa.expshare.class001.chemicalmatch.entity.po.NickNameMongoData;
import indi.zhifa.expshare.class001.chemicalmatch.enums.EConstEnum;
import indi.zhifa.expshare.class001.chemicalmatch.enums.EModuleType;
import indi.zhifa.expshare.class001.chemicalmatch.util.redis.INickRedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.util.StringUtils;

import java.util.*;

@Slf4j
public class ChemicalNickNameListener implements ReadListener<ChemicalNickNameExcelData> {

    List<ChemicalNickNameExcelData> mChemicalNickNameExcelDataList;
    final MongoTemplate mMongoTemplate;
    final INickNameRepository mNickNameRepository;
    final INickRedisUtil mNickRedisUtil;

    public ChemicalNickNameListener(MongoTemplate pMongoTemplate,
                                    INickNameRepository pNickNameRepository,
                                    INickRedisUtil pNickRedisUtil){
        mChemicalNickNameExcelDataList = new ArrayList<>();
        mMongoTemplate = pMongoTemplate;
        mNickNameRepository = pNickNameRepository;
        mNickRedisUtil = pNickRedisUtil;
    }

    @Override
    public void invoke(ChemicalNickNameExcelData data, AnalysisContext context) {
        mChemicalNickNameExcelDataList.add(data);
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {

        // 添加化学别名索引
        mNickRedisUtil.addIndex(EModuleType.CHEMICAL.name(), EConstEnum.SUBMODULE_NONE.getCode());

        Criteria criteria = Criteria.where("module").is(EModuleType.CHEMICAL);
        List<NickNameMongoData> nickNameMongoDataList = mMongoTemplate.find(new Query(criteria),
                NickNameMongoData.class);
        Map<String, NickNameMongoData> nickNameMap = new HashMap<>();
        for(NickNameMongoData data : nickNameMongoDataList){
            nickNameMap.put(data.getName(), data);
        }

        List<NickNameMongoData> newNickNameList = new ArrayList<>();
        List<NickNameMongoData> updateNickNameList = new ArrayList<>();


        for(ChemicalNickNameExcelData data : mChemicalNickNameExcelDataList){

            NickNameMongoData nickNameMongoData = null;
            boolean isUpdate = false;
            boolean isNew = false;
            if(nickNameMap.containsKey(data.getName())){
                nickNameMongoData = nickNameMap.get(data.getName());
                updateNickNameList.add(nickNameMongoData);
            }else{
                nickNameMongoData = new NickNameMongoData();
                nickNameMongoData.initByChemical();
                nickNameMongoData.setName(data.getName());
                isNew = true;
            }
            List<String> nickNameList = nickNameMongoData.getNickNames();
            Set<String> nickNameSet = new HashSet<>(nickNameList);
            List<String> theNewNickNameList = new ArrayList<>();


            List<String> excelNickNames = Arrays.asList(
                    data.getName(),
                    data.getEnNameExt1(),
                    data.getEnNameExt2(),
                    data.getEnNameExt3(),
                    data.getEnNameExt4(),
                    data.getEnNameExt5(),
                    data.getCnName(),
                    data.getCnNameExt1(),
                    data.getCnNameExt2(),
                    data.getCnNameExt3(),
                    data.getCnNameExt4(),
                    data.getCnNameExt5());
            for(String nickName : excelNickNames){
                if(!StringUtils.hasLength(nickName) || nickName.isBlank()){
                    continue;
                }
                nickName = nickName.trim();
                if(!nickNameSet.contains(nickName)){
                    isUpdate = true;
                    nickNameList.add(nickName);
                    theNewNickNameList.add(nickName);
                }
            }
            if(isNew){
                newNickNameList.add(nickNameMongoData);
            }
            if(isUpdate){
                mNickRedisUtil.addNickName(nickNameMongoData.getModule().name(),
                        nickNameMongoData.getSubModule(),
                        nickNameMongoData.getName(),
                        nickNameMongoData.getNickNames());
            }
        }
        mNickNameRepository.insert(newNickNameList);
        mNickNameRepository.saveAll(updateNickNameList);
    }
}
